home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Resource Library: Multimedia
/
Resource Library: Multimedia.iso
/
hypertxt
/
msdos
/
ebksrc
/
pcled.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1991-07-30
|
7KB
|
333 lines
/*
pcled.cpp
7-30-91
Line Edit for the IBM PC Text Modes.
Copyright 1991
John W. Small
All rights reserved
Use freely but acknowledge authorship and copyright.
PSW / Power SoftWare
P.O. Box 10072
McLean, Virginia 22102 8072 USA
Voice: (703) 759-3838
CIS: 73757,2233
*/
#include <ctype.h>
#include <string.h>
#include <conio.h>
#include <pckey.hpp>
#include <pcled.hpp>
Palette LineEdit::defaultP = {
0, /* monochrome or color */
svideo(WHITE,BLACK), svideo(BLACK,LIGHTGRAY),
svideo(BLACK,LIGHTGRAY), svideo(BLUE,LIGHTGRAY),
svideo(DARKGRAY,LIGHTGRAY), svideo(WHITE,BLUE)
};
int LineEdit::edit(char *response, int sizeofResponse,
int flen, int x, int y, const char *pref,
const char *prompt, TFvaliD validate)
{
struct text_info ti;
CursorShape cursor;
int maxlen, insmode, rlen, i, fscol, c, erase, j;
int owscroll;
int w, h;
if ((maxlen = sizeofResponse - 1) < 1 || flen < 1)
return 0;
gettextinfo(&ti);
w = ti.winright - ti.winleft + 1;
h = ti.winbottom - ti.wintop + 1;
if (x < 1 || y < 1) {
x = wherex();
y = wherey();
}
else if (x + (prompt?strlen(prompt)+2:0)
>= w - 1 || y > h)
return 0;
// two extra spaces required for arrows
cursor.saveOrig();
owscroll = _wscroll;
_wscroll = 0;
mappalette(P);
insmode = 1;
cursor.normal();
gotoxy(x,y);
if (prompt) {
mapvideo(PROMPT,P);
cprintf("%s: ",prompt);
}
if (pref) {
i = strlen(pref);
strncpy(response,pref,maxlen);
if (i > maxlen)
i = maxlen;
}
else
i = 0;
response[rlen = i] = '\0'; /* i & fscol are zero biased */
x = wherex(); y = wherey();
/* leave two extra spaces for backward and forward arrows */
if (flen > w-x-1)
flen = w-x-1;
if (i > flen)
fscol = i + 1 - flen;
else
fscol = 0;
erase = 1;
mapvideo(RESPONSE,P);
while (1) {
cursor.off();
gotoxy(x,y);
if (erase) {
putch(fscol?'\021':' ');
mapvideo(PREFERENCE,P);
j = cprintf("%-.*s",flen,&response[fscol]);
mapvideo(RESPONSE,P);
cprintf("%*.s",flen-j,"");
putch((fscol+flen < rlen)?'\020':' ');
}
else
cprintf("%c%-*.*s%c",(fscol?'\021':' '),
flen,flen,&response[fscol],
((fscol+flen<rlen)?'\020':' '));
/* leave extra space for backward arrow */
gotoxy(x+i-fscol+1,y);
cursor.on();
c = PCK.getkey();
switch (c) {
case -Home:
fscol = i = 0;
break;
case -EndKey:
i = rlen;
if (i >= fscol + flen)
fscol = i+1 - flen;
break;
case CtrlS:
case -LArr:
if (i)
if (--i < fscol)
fscol = i;
break;
case CtrlA:
case -CtrlLArr:
while (i && !isalnum(response[i-1])) i--;
while (i && isalnum(response[i-1])) i--;
if (i < fscol)
fscol = i;
break;
case CtrlD:
case -RArr:
if (i < rlen)
if (++i >= fscol + flen)
fscol = i+1 - flen;
break;
case CtrlF:
case -CtrlRArr:
while (i < rlen && isalnum(response[i])) i++;
while (i < rlen && !isalnum(response[i])) i++;
if (i >= fscol + flen)
fscol = i+1 - flen;
break;
case -UpArr:
case -DnArr:
if (pref) {
i = strlen(pref);
strncpy(response,pref,maxlen);
if (i > maxlen)
i = maxlen;
response[rlen = i] = '\0';
/* i & fscol are zero biased */
if (i > flen)
fscol = i + 1 - flen;
else
fscol = 0;
erase = 1;
continue;
}
break;
case CtrlV:
case -InsKey:
if (insmode) {
cursor.block();
insmode = 0;
}
else {
cursor.normal();
insmode = 1;
}
break;
case -DelKey:
if (response[i] && rlen) {
strcpy(&response[i],&response[i+1]);
rlen--;
}
break;
case CR:
if (validate)
if (!(*validate)(response,maxlen)) {
putch('\a');
erase = 1;
continue;
}
gotoxy(x,y);
cprintf(" %-*.*s ",flen,flen,response);
gotoxy(x+1,y);
_wscroll = owscroll;
textattr(ti.attribute);
cursor.restoreOrig();
return 1;
case ESC:
response[i=0] = '\0';
gotoxy(x,y);
cprintf(" %-*.*s ",flen,flen,response);
gotoxy(x+1,y);
_wscroll = owscroll;
textattr(ti.attribute);
cursor.restoreOrig();
return 0;
case BACKSP: /* CtrlH */
if (i) {
strcpy(&response[i-1],&response[i]);
rlen--;
if (--i < fscol)
fscol = i;
else if (fscol)
fscol--;
}
break;
case CtrlT:
if (i == rlen) break;
if (isalnum(response[i]))
while (isalnum(response[i]) && i < rlen) {
strcpy(&response[i],&response[i+1]);
rlen--;
}
else if (!isspace(response[i])) {
strcpy(&response[i],&response[i+1]);
rlen--;
}
while (isspace(response[i]) && i < rlen) {
strcpy(&response[i],&response[i+1]);
rlen--;
}
break;
case CtrlY:
response[rlen = fscol = i = 0] = '\0';
break;
case CtrlQ:
cursor.off();
gotoxy(x,y);
blinkvideo();
putch('Q');
unblinkvideo();
gotoxy(x+i-fscol+1,y);
cursor.on();
switch (PCK.getkey()) {
case CtrlY:
case 'Y':
case 'y':
response[rlen = i] = '\0';
break;
case CtrlS:
case 'S':
case 's':
fscol = i = 0;
break;
case CtrlD:
case 'D':
case 'd':
i = rlen;
if (i >= fscol + flen)
fscol = i+1 - flen;
break;
default:
putch('\a');
break;
}
break;
case TAB: // tabs not allowed
putch('\a');
break;
default:
if (isprint(c) && rlen <= maxlen) {
if (erase) {
response[rlen = fscol = i = 0] = '\0';
gotoxy(x,y);
cprintf(" %-*.*s ",flen,flen,response);
}
if (insmode || i >= rlen) {
if (rlen == maxlen) {
putch('\a');
break;
}
for (j = rlen; j >= i; j--)
response[j+1] = response[j];
rlen++;
}
response[i] = c;
if (i < rlen)
if (++i >= fscol + flen)
fscol = i+1 - flen;
}
else
putch('\a');
break;
}
erase = 0;
}
}
int LineEditWindow::edit(char *response, int sizeofResponse,
int flen, int x, int y, const char *pref,
const char *prompt, TFvaliD validate)
{
struct text_info ti;
if (sizeofResponse < 2 || flen < 1)
return 0;
if (flen > sizeofResponse)
flen = sizeofResponse;
gettextinfo(&ti);
if (x < 1 || y < 1 ||
x + flen + 3 > ti.screenwidth ||
y + 3 > ti.screenheight) {
x = ti.screenwidth/2 - flen/2 - 2;
y = ti.screenheight/2 - 1;
}
if (!window(x,y,x+3+flen,y+2))
return 0;
if (prompt)
putTitle(prompt);
int ok = LineEdit::edit(response,sizeofResponse,
flen,1,1,pref,(char *)0,validate);
close();
return ok;
}